lib/sign: new function for summary file signing
authorDenis Pynkin <denis.pynkin@collabora.com>
Tue, 26 Nov 2019 09:44:44 +0000 (12:44 +0300)
committerDenis Pynkin <denis.pynkin@collabora.com>
Wed, 25 Mar 2020 12:23:55 +0000 (15:23 +0300)
Add function `ostree_sign_summary()` allowing to sign the summary file.

Signed-off-by: Denis Pynkin <denis.pynkin@collabora.com>
apidoc/ostree-sections.txt
src/libostree/libostree-devel.sym
src/libostree/ostree-sign.c
src/libostree/ostree-sign.h

index 9b71d610f2e6be8beaa8e395c65180ce5f4a56b1..a5a632a5f091635049ab85a9d545f05ed880201e 100644 (file)
@@ -723,6 +723,7 @@ ostree_sign_clear_keys
 ostree_sign_load_pk
 ostree_sign_set_pk
 ostree_sign_set_sk
+ostree_sign_summary
 <SUBSECTION Standard>
 ostree_sign_get_type
 ostree_sign_dummy_get_type
index a10ec266484f7a924f511b0eebcef1faa59b59e1..29221f5d41c0529e733644aca06189cecce509a0 100644 (file)
@@ -35,6 +35,7 @@ global:
   ostree_sign_set_pk;
   ostree_sign_add_pk;
   ostree_sign_set_sk;
+  ostree_sign_summary;
   ostree_sign_dummy_get_type;
   ostree_sign_ed25519_get_type;
 } LIBOSTREE_2020.1;
index 75db0b26a2e22e5d92d161de6adc5e5e06ab88f7..e7962425e7f5e17992c16bd2e2fbd29ad971572b 100644 (file)
@@ -48,6 +48,7 @@
 #endif
 
 #include "ostree-autocleanups.h"
+#include "ostree-repo-private.h"
 
 #undef G_LOG_DOMAIN
 #define G_LOG_DOMAIN "OSTreeSign"
@@ -594,3 +595,98 @@ ostree_sign_get_by_name (const gchar *name, GError **error)
 
   return sign;
 }
+
+/**
+ * ostree_sign_summary:
+ * @self: Self
+ * @repo: ostree repository
+ * @keys: keys -- GVariant containing keys as GVarints specific to signature type.
+ * @cancellable: A #GCancellable
+ * @error: a #GError
+ *
+ * Add a signature to a summary file.
+ * Based on ostree_repo_add_gpg_signature_summary implementation.
+ *
+ * Returns: @TRUE if summary file has been signed with all provided keys
+ */
+gboolean
+ostree_sign_summary (OstreeSign    *self,
+                     OstreeRepo    *repo,
+                     GVariant      *keys,
+                     GCancellable  *cancellable,
+                     GError       **error)
+{
+  g_debug ("%s enter", __FUNCTION__);
+  g_return_val_if_fail (OSTREE_IS_SIGN (self), FALSE);
+  g_return_val_if_fail (OSTREE_IS_REPO (repo), FALSE);
+
+  gboolean ret = FALSE;
+
+  g_autoptr(GVariant) normalized = NULL;
+  g_autoptr(GBytes) summary_data = NULL;
+  g_autoptr(GVariant) metadata = NULL;
+
+  glnx_autofd int fd = -1;
+  if (!glnx_openat_rdonly (repo->repo_dir_fd, "summary", TRUE, &fd, error))
+    goto out;
+  summary_data = ot_fd_readall_or_mmap (fd, 0, error);
+  if (!summary_data)
+    goto out;
+
+  /* Note that fd is reused below */
+  glnx_close_fd (&fd);
+
+  if (!ot_openat_ignore_enoent (repo->repo_dir_fd, "summary.sig", &fd, error))
+    goto out;
+  if (fd >= 0)
+    {
+      if (!ot_variant_read_fd (fd, 0, OSTREE_SUMMARY_SIG_GVARIANT_FORMAT,
+                               FALSE, &metadata, error))
+        goto out;
+    }
+
+  if (g_variant_n_children(keys) == 0)
+    {
+      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                           "No keys passed for signing summary");
+      goto out;
+    }
+
+  GVariantIter *iter;
+  GVariant *key;
+
+  g_variant_get (keys, "av", &iter);
+  while (g_variant_iter_loop (iter, "v", &key))
+    {
+      g_autoptr (GBytes) signature = NULL;
+
+      if (!ostree_sign_set_sk (self, key, error))
+        goto out;
+
+      if (!ostree_sign_data (self,
+                             summary_data,
+                             &signature,
+                             cancellable,
+                             error))
+        goto out;
+
+      g_autoptr(GVariant) old_metadata = g_steal_pointer (&metadata);
+      metadata =
+        _sign_detached_metadata_append (self, old_metadata, signature);
+    }
+  g_variant_iter_free (iter);
+
+  normalized = g_variant_get_normal_form (metadata);
+  if (!_ostree_repo_file_replace_contents (repo,
+                                           repo->repo_dir_fd,
+                                           "summary.sig",
+                                           g_variant_get_data (normalized),
+                                           g_variant_get_size (normalized),
+                                           cancellable, error))
+    goto out;
+
+  ret = TRUE;
+
+out:
+  return ret;
+}
index 1415becb6c25613e356d3117d8e9719bd855a379..678f182ddbe0deb3757d6a6d6031d4607cb91d55 100644 (file)
@@ -152,5 +152,11 @@ GStrv ostree_sign_list_names(void);
 _OSTREE_PUBLIC
 OstreeSign * ostree_sign_get_by_name (const gchar *name, GError **error);
 
+_OSTREE_PUBLIC
+gboolean ostree_sign_summary (OstreeSign    *self,
+                              OstreeRepo    *repo,
+                              GVariant      *keys,
+                              GCancellable  *cancellable,
+                              GError       **error);
 G_END_DECLS